/************************************************************

Teste da diretiva monitor

************************************************************/#include <cpar.h>
static CPARContext *pGlobalContext;
typedef struct CPARGlobalStackData{
long __CPAR_VERSION__;
CPARMutex *buffer;
 char c;
char mmm;
}CPARGlobalStackData;
typedef struct CPARTaskStackData_consumidor{
char x;
}CPARTaskStackData_consumidor;
typedef struct CPARTaskStackData_produtor{
char x;
}CPARTaskStackData_produtor;
static CPARGlobalStackData *pGlobalStack;

#include <conio.h>
#include <stdio.h>

void CPARMonitor_buffer__create () { CPARMutexCreate(CPARContextAllocatorGet(pGlobalContext),&(pGlobalStack->buffer));pGlobalStack->c=0;}void CPARMonitor_buffer__destroy () { CPARMutexDestroy(pGlobalStack->buffer);}void escrever(char carac)
   {
      if(pGlobalStack->c==0)
         pGlobalStack->c=carac;
   }void CPARMonitor_buffer_escrever(char carac){CPARMutexLock(pGlobalStack->buffer);escrever(carac);CPARMutexUnlock(pGlobalStack->buffer);}char ler()
   {
      char ch;
	  
	  ch = 0;
	  
      if(pGlobalStack->c!=0)
      {
         ch=pGlobalStack->c;
         pGlobalStack->c=0;
      }
      return ch;
   }char CPARMonitor_buffer_ler(){char __return_data;CPARMutexLock(pGlobalStack->buffer);__return_data = ler();CPARMutexUnlock(pGlobalStack->buffer);return __return_data;}

void CPARTask_produtor(CPARContext *pContext);
void CPARTask_produtor(CPARContext *pContext)
{CPARTaskStackData_produtor *pStack; pStack = (CPARTaskStackData_produtor*) CPARContextStackGet(pContext);
   
   do
   {
      pStack->x=_getch();
	  if(pStack->x > 0)
		CPARMonitor_buffer_escrever(pStack->x);
   } while (pStack->x!='.');
}

void CPARTask_consumidor(CPARContext *pContext);
void CPARTask_consumidor(CPARContext *pContext)
{CPARTaskStackData_consumidor *pStack; pStack = (CPARTaskStackData_consumidor*) CPARContextStackGet(pContext);
   
   while ( (pStack->x=CPARMonitor_buffer_ler()) != '.')
   {
		if(pStack->x > 0)
			putchar(pStack->x);
   }
}
int main(int argc, char **argv)
{
	CPARInit();if( CPARContextCreate( NULL, &pGlobalContext, sizeof(CPARGlobalStackData) )){  CPAR_ERROR("Falha ao alocar contexto global");  return CPAR_E_NO_MEMORY;}pGlobalStack = (CPARGlobalStackData*) CPARContextStackGet(pGlobalContext);CPARMonitor_buffer__create();
   if( CPARContextWorkPoolCreate( pGlobalContext, 2)){CPAR_ERROR("Falha ao alocar work pool");return -1;}CPAR_DEFINE_VERSION;;
   CPARContextTaskDispatch(pGlobalContext,1,CPARTask_produtor,sizeof(CPARTaskStackData_produtor));
   CPARContextTaskDispatch(pGlobalContext,1,CPARTask_consumidor,sizeof(CPARTaskStackData_consumidor));
   CPARContextTaskWaitAll(pGlobalContext);
CPARMonitor_buffer__destroy();return 0;}
